package com.gzc.just.play.client.war3server;

import com.gzc.just.play.Const;
import com.gzc.just.play.client.ConnectionWar3ProxyServer;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

import java.net.*;

class War3UdpListener implements Runnable {
    private static final Logger logger = LogManager.getLogger(War3UdpListener.class);
    
    private final String otherWar3Ip;
    private final ConnectionWar3ProxyServer connectionWar3ProxyServer;
    private volatile DatagramSocket _socket;

    public War3UdpListener(String otherWar3Ip, ConnectionWar3ProxyServer connectionWar3ProxyServer) {
        this.otherWar3Ip = otherWar3Ip;
        this.connectionWar3ProxyServer = connectionWar3ProxyServer;
    }

    @Override
    public void run() {
        logger.info("war3UdpListener start,otherWar3Ip={},port={}", otherWar3Ip, Const.WAR3_PORT);
        try (DatagramSocket socket = new DatagramSocket(new InetSocketAddress(otherWar3Ip, Const.WAR3_PORT))) {
            socket.setBroadcast(true); // 允许广播
            _socket = socket;
            byte[] receiveData = new byte[1024];
            logger.info("war3UdpListener start ok,otherWar3Ip={},port={}", otherWar3Ip, Const.WAR3_PORT);

            while (!Thread.interrupted()) {
                try {
                    DatagramPacket packet = new DatagramPacket(receiveData, receiveData.length);
                    socket.receive(packet);
                    // 收到其他ip的udp数据，转发给proxyServer
                    if (!packet.getAddress().getHostAddress().equals(otherWar3Ip)) {
                        logger.info("receive udp data from ip={},port={},packetLen={}",
                                packet.getAddress().getHostAddress(), packet.getPort(), packet.getLength());
                        connectionWar3ProxyServer.forwardUdpDataToServer(otherWar3Ip, packet.getData(), packet.getLength());
                    }
                } catch (SocketException e) {
                    if (Thread.currentThread().isInterrupted()) {
                        // 正常中断，仅记录调试信息
                        logger.debug("UDP socket closed due to thread interruption", e);
                    } else {
                        // 非预期的Socket异常，记录为错误
                        logger.error("Unexpected socket closure", e);
                    }
                } catch (Exception e) {
                    logger.error(e.getMessage(), e);
                }
            }
        } catch (Exception e) {
            logger.error(e.getMessage(), e);
        }
    }

    public void send(byte[] data) {
        if (null == _socket) {
            logger.error("war3UdpListener socket is null,otherWar3Ip={}", otherWar3Ip);
            return;
        }
        if (_socket.isClosed()) {
            logger.error("war3UdpListener socket is closed,otherWar3Ip={}", otherWar3Ip);
            return;
        }

        try {
            // 获取子网广播地址
            InetAddress localAddress = _socket.getLocalAddress();
            InetAddress broadcastAddress = getSubnetBroadcastAddress(localAddress);

            logger.info("Sending UDP packet to broadcastAddress={},war3port={},size={}",
                    broadcastAddress.getHostAddress(), Const.WAR3_PORT, data.length);
            DatagramPacket packet = new DatagramPacket(data, data.length, broadcastAddress, Const.WAR3_PORT);
            _socket.send(packet);
        } catch (Exception e) {
            logger.error("war3UdpListener send udp data error,otherWar3Ip={}", otherWar3Ip, e);
        }
    }

    // 新增的子网广播地址获取方法
    private InetAddress getSubnetBroadcastAddress(InetAddress localAddress) throws Exception {
        NetworkInterface ni = NetworkInterface.getByInetAddress(localAddress);
        if (ni != null) {
            for (InterfaceAddress ia : ni.getInterfaceAddresses()) {
                if (ia.getAddress().equals(localAddress)) {
                    return ia.getBroadcast();
                }
            }
        }
        // 默认回退到全局广播
        return InetAddress.getByName(Const.Broadcast_Address);
    }
}
